/**
 * 数独游戏完整实现
 */
const SudokuGame = (function() {
    // 游戏状态
    const state = {
        difficulty: 1, // 1:容易, 2:中等, 3:困难, 4:专家
        currentLevel: 1,
        board: Array(9).fill().map(() => Array(9).fill(0)),
        solution: Array(9).fill().map(() => Array(9).fill(0)),
        notes: Array(9).fill().map(() => Array(9).fill().map(() => [])),
        timeElapsed: 0,
        mistakes: 0,
        maxMistakes: 3,
        moves: [],
        notesMode: false,
        isPlaying: false,
        selectedCell: null,
        timer: null,
        puzzles: {
            easy: [],
            medium: [],
            hard: [],
            expert: []
        },
        progress: {
            easy: Array(20).fill(false),
            medium: Array(20).fill(false),
            hard: Array(20).fill(false),
            expert: Array(20).fill(false)
        }
    };

    // DOM元素
    const elements = {
        // 页面容器
        mainPage: document.getElementById('main-page'),
        difficultyPage: document.getElementById('difficulty-page'),
        levelPage: document.getElementById('level-page'),
        gamePage: document.getElementById('game-page'),
        
        // 主菜单按钮
        startGameBtn: document.getElementById('start-game-btn'),
        continueGameBtn: document.getElementById('continue-game-btn'),
        newGameBtn: document.getElementById('new-game-btn'),
        
        // 难度选择按钮
        easyBtn: document.getElementById('easy-btn'),
        mediumBtn: document.getElementById('medium-btn'),
        hardBtn: document.getElementById('hard-btn'),
        expertBtn: document.getElementById('expert-btn'),
        cancelBtn: document.getElementById('cancel-btn'),
        
        // 关卡选择
        levelGrid: document.getElementById('level-grid'),
        levelDifficultyTitle: document.getElementById('level-difficulty-title'),
        levelBackBtn: document.getElementById('level-back-btn'),
        
        // 游戏页面元素
        backBtn: document.getElementById('back-btn'),
        levelInfo: document.getElementById('level-info'),
        hearts: document.querySelectorAll('.heart'),
        timerDisplay: document.querySelector('.timer'),
        sudokuBoard: document.getElementById('sudoku-board'),
        
        // 控制按钮
        undoBtn: document.getElementById('undo-btn'),
        eraseBtn: document.getElementById('erase-btn'),
        notesBtn: document.getElementById('notes-btn'),
        hintBtn: document.getElementById('hint-btn'),
        
        // 数字按钮容器
        numberSelector: document.querySelector('.number-selector'),
        
        // 游戏结束弹窗
        gameOverPopup: document.getElementById('game-over-popup'),
        overlay: document.getElementById('overlay'),
        gameResult: document.getElementById('game-result'),
        difficultyDisplay: document.getElementById('difficulty-display'),
        levelDisplay: document.getElementById('level-display'),
        timeDisplay: document.getElementById('time-display'),
        nextLevelInfo: document.getElementById('next-level-info'),
        nextLevelBtn: document.getElementById('next-level-btn'),
        playAgainBtn: document.getElementById('play-again-btn'),
        returnHomeBtn: document.getElementById('return-home-btn')
    };

    // 初始化游戏
    function init() {
        // 创建数字按钮
        createNumberButtons();
        
        setupEventListeners();
        loadProgress();
        generatePuzzles();
        updateMenuButtons();
        showMainMenu();
    }

    // 创建数字选择按钮
    function createNumberButtons() {
        elements.numberSelector.innerHTML = '';
        
        for (let i = 1; i <= 9; i++) {
            const btn = document.createElement('button');
            btn.className = 'number-btn';
            btn.textContent = i;
            btn.dataset.number = i;
            btn.addEventListener('click', () => fillNumber(i));
            elements.numberSelector.appendChild(btn);
        }
    }

    // 设置事件监听器
    function setupEventListeners() {
        // 主菜单按钮
        elements.startGameBtn.addEventListener('click', showDifficultyMenu);
        elements.continueGameBtn.addEventListener('click', loadGame);
        elements.newGameBtn.addEventListener('click', showDifficultyMenu);
        
        // 难度选择按钮
        elements.easyBtn.addEventListener('click', () => showLevelMenu(1));
        elements.mediumBtn.addEventListener('click', () => showLevelMenu(2));
        elements.hardBtn.addEventListener('click', () => showLevelMenu(3));
        elements.expertBtn.addEventListener('click', () => showLevelMenu(4));
        elements.cancelBtn.addEventListener('click', showMainMenu);
        
        // 关卡选择按钮
        elements.levelBackBtn.addEventListener('click', showDifficultyMenu);
        
        // 游戏页面按钮
        elements.backBtn.addEventListener('click', () => {
            if(confirm("确定要退出当前游戏吗?游戏进度将会自动保存。")) {
                saveCurrentGame();
                showLevelMenu(state.difficulty);
            }
        });
        
        elements.undoBtn.addEventListener('click', undoMove);
        elements.eraseBtn.addEventListener('click', eraseCell);
        elements.notesBtn.addEventListener('click', toggleNotes);
        elements.hintBtn.addEventListener('click', giveHint);
        
        // 游戏结束弹窗按钮
        elements.nextLevelBtn.addEventListener('click', nextLevel);
        elements.playAgainBtn.addEventListener('click', playAgain);
        elements.returnHomeBtn.addEventListener('click', showMainMenu);
    }

    // 显示主菜单
    function showMainMenu() {
        elements.gamePage.classList.remove("active");
        elements.levelPage.classList.remove("active");
        elements.difficultyPage.classList.remove("active");
        elements.mainPage.classList.add("active");
    }

    // 显示难度选择菜单
    function showDifficultyMenu() {
        elements.gamePage.classList.remove("active");
        elements.levelPage.classList.remove("active");
        elements.difficultyPage.classList.add("active");
        elements.mainPage.classList.remove("active");
    }

    // 获取难度键名
    function getDifficultyKey(difficulty) {
        switch(difficulty) {
            case 1: return 'easy';
            case 2: return 'medium';
            case 3: return 'hard';
            case 4: return 'expert';
            default: return 'medium';
        }
    }

    // 显示关卡选择菜单
    function showLevelMenu(difficulty) {
        state.difficulty = difficulty;
        
        let difficultyText;
        switch(difficulty) {
            case 1: difficultyText = "容易"; break;
            case 2: difficultyText = "中等"; break;
            case 3: difficultyText = "困难"; break;
            case 4: difficultyText = "专家"; break;
            default: difficultyText = "未知";
        }
        
        elements.levelDifficultyTitle.textContent = `${difficultyText} - 关卡选择`;
        elements.levelGrid.innerHTML = "";
        
        const difficultyKey = getDifficultyKey(difficulty);
        
        for(let i = 0; i < 20; i++) {
            const levelBtn = document.createElement("button");
            levelBtn.className = "level-btn";
            
            // 第一关总是解锁,或者前一关已完成
            if(i === 0 || state.progress[difficultyKey][i-1]) {
                levelBtn.textContent = i + 1;
                levelBtn.addEventListener("click", () => startLevel(i + 1));
                
                if(state.progress[difficultyKey][i]) {
                    levelBtn.classList.add("completed");
                }
            } else {
                levelBtn.textContent = "🔒";
                levelBtn.classList.add("locked");
            }
            
            elements.levelGrid.appendChild(levelBtn);
        }
        
        elements.gamePage.classList.remove("active");
        elements.levelPage.classList.add("active");
        elements.difficultyPage.classList.remove("active");
        elements.mainPage.classList.remove("active");
    }

    // 开始关卡
    function startLevel(level) {
        state.currentLevel = level;
        const difficultyKey = getDifficultyKey(state.difficulty);
        
        // 设置棋盘和解决方案
        state.board = JSON.parse(JSON.stringify(state.puzzles[difficultyKey][level-1].puzzle));
        state.solution = JSON.parse(JSON.stringify(state.puzzles[difficultyKey][level-1].solution));
        
        // 重置游戏状态
        state.timeElapsed = 0;
        state.isPlaying = true;
        state.mistakes = 0;
        state.moves = [];
        state.notesMode = false;
        state.notes = Array(9).fill().map(() => Array(9).fill().map(() => []));
        state.selectedCell = null;
        
        // 更新笔记按钮状态
        elements.notesBtn.classList.remove("highlighted");
        
        // 设置关卡信息显示
        let difficultyText;
        switch(state.difficulty) {
            case 1: difficultyText = "容易"; break;
            case 2: difficultyText = "中等"; break;
            case 3: difficultyText = "困难"; break;
            case 4: difficultyText = "专家"; break;
            default: difficultyText = "中等";
        }
        
        elements.levelInfo.textContent = `关卡 ${level} ${difficultyText}`;
        
        // 重置红心
        updateHearts();
        
        // 渲染棋盘
        renderBoard();

        checkNumberCompletion(); 
        
        // 开始计时
        startTimer();
        
        // 切换到游戏页面
        elements.levelPage.classList.remove("active");
        elements.gamePage.classList.add("active");
    }

    // 渲染棋盘
    function renderBoard() {
        elements.sudokuBoard.innerHTML = "";
        
        for(let i = 0; i < 9; i++) {
            for(let j = 0; j < 9; j++) {
                const cell = document.createElement("div");
                cell.className = "cell";
                
                // 设置固定单元格样式
                if(state.board[i][j] !== 0 && state.board[i][j] === state.solution[i][j]) {
                    cell.classList.add("fixed");
                }
                
                // 显示数字或笔记
                if(state.board[i][j] !== 0) {
                    cell.textContent = state.board[i][j];
                } else if(state.notes[i][j].length > 0) {
                    cell.innerHTML = state.notes[i][j].map(n => `<small>${n}</small>`).join("");
                }
                
                cell.addEventListener("click", () => selectCell(cell, i, j));
                elements.sudokuBoard.appendChild(cell);
            }
        }
        
        // 保持选中状态
        if(state.selectedCell) {
            const { row, col } = state.selectedCell;
            const newCell = elements.sudokuBoard.children[row * 9 + col];
            newCell.classList.add("highlighted");
            state.selectedCell.element = newCell;
        }
    }

    // 检查数字是否已全部填完
function checkNumberCompletion() {
    const numberCounts = Array(10).fill(0); // 1-9的数字计数
    const solutionCounts = Array(10).fill(0); // 解决方案中1-9的数字计数
    
    // 统计当前棋盘和解决方案中的数字数量
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            const num = state.board[i][j];
            if (num !== 0) {
                numberCounts[num]++;
            }
            const solutionNum = state.solution[i][j];
            solutionCounts[solutionNum]++;
        }
    }
    
    // 更新数字按钮状态
    const numberButtons = document.querySelectorAll('.number-btn');
    numberButtons.forEach(btn => {
        const num = parseInt(btn.dataset.number);
        if (numberCounts[num] === solutionCounts[num]) {
            btn.classList.add('completed');
            btn.disabled = true;
        } else {
            btn.classList.remove('completed');
            btn.disabled = false;
        }
    });
}

    // 选择单元格
    function selectCell(cell, row, col) {
        // 取消之前选中的单元格
        if(state.selectedCell) {
            state.selectedCell.element.classList.remove("highlighted");
        }
        
        // 选中新单元格
        state.selectedCell = { element: cell, row, col };
        cell.classList.add("highlighted");
    }

    // 填充数字
    function fillNumber(number) {
        if(!state.selectedCell || !state.isPlaying) return;
        
        const { element, row, col } = state.selectedCell;
        
        // 检查是否是固定单元格
        if(element.classList.contains("fixed")) return;
        
        // 记录移动(用于撤销)
        state.moves.push({
            row, col,
            previousValue: state.board[row][col],
            newValue: number,
            previousNotes: [...state.notes[row][col]]
        });
        
        if(state.notesMode) {
            // 笔记模式
            const index = state.notes[row][col].indexOf(number);
            if(index === -1) {
                state.notes[row][col].push(number);
                state.notes[row][col].sort();
            } else {
                state.notes[row][col].splice(index, 1);
            }
            // 清空单元格的值
            state.board[row][col] = 0;
        } else {
            // 正常模式
            state.notes[row][col] = [];
            state.board[row][col] = number;
            
            // 检查是否正确
            if(number !== state.solution[row][col]) {
                // 错误
                element.classList.add("error");
                state.mistakes++;
                updateHearts();
                
                // 0.5秒后移除错误样式
                setTimeout(() => {
                    element.classList.remove("error");
                }, 500);
            } else {
                // 正确，检查是否完成
                if(isBoardComplete()) {
                    gameOver(true);
                }
            }
        }
        
        // 重新渲染棋盘
        renderBoard();
         checkNumberCompletion(); // 新增
    }

    // 擦除单元格
    function eraseCell() {
        if(!state.selectedCell || !state.isPlaying) return;
        
        const { element, row, col } = state.selectedCell;
        if(element.classList.contains("fixed")) return;
        
        // 记录移动(用于撤销)
        state.moves.push({
            row, col,
            previousValue: state.board[row][col],
            newValue: 0,
            previousNotes: [...state.notes[row][col]]
        });
        
        // 清除单元格
        state.board[row][col] = 0;
        state.notes[row][col] = [];
        
        // 重新渲染棋盘
        renderBoard();
    }

    // 撤销上一步
    function undoMove() {
        if(!state.isPlaying || state.moves.length === 0) return;
        
        const move = state.moves.pop();
        const { row, col, previousValue, previousNotes } = move;
        
        // 恢复状态
        state.board[row][col] = previousValue;
        state.notes[row][col] = previousNotes;
        
        // 重新渲染棋盘
        renderBoard();
    }

    // 切换笔记模式
    function toggleNotes() {
        state.notesMode = !state.notesMode;
        elements.notesBtn.classList.toggle("highlighted", state.notesMode);
    }

    // 提供提示
    function giveHint() {
        if(!state.selectedCell || !state.isPlaying) return;
        
        const { row, col } = state.selectedCell;
        const correctNumber = state.solution[row][col];
        
        // 记录移动(用于撤销)
        state.moves.push({
            row, col,
            previousValue: state.board[row][col],
            newValue: correctNumber,
            previousNotes: [...state.notes[row][col]]
        });
        
        // 填充正确数字
        state.board[row][col] = correctNumber;
        state.notes[row][col] = [];
        
        // 重新渲染棋盘
        renderBoard();
        checkNumberCompletion(); 
        
        // 检查是否完成
        if(isBoardComplete()) {
            gameOver(true);
        }
    }

    // 检查棋盘是否完成
    function isBoardComplete() {
        for(let i = 0; i < 9; i++) {
            for(let j = 0; j < 9; j++) {
                if(state.board[i][j] !== state.solution[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    // 开始计时器
    function startTimer() {
        if(state.timer) clearInterval(state.timer);
        
        state.timer = setInterval(() => {
            state.timeElapsed++;
            updateTimerDisplay();
        }, 1000);
    }

    // 更新计时器显示
    function updateTimerDisplay() {
        const minutes = Math.floor(state.timeElapsed / 60);
        const seconds = state.timeElapsed % 60;
        elements.timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
    }

    // 更新红心显示
    function updateHearts() {
        elements.hearts.forEach((heart, index) => {
            heart.style.visibility = index < state.maxMistakes - state.mistakes ? "visible" : "hidden";
        });
        
        // 检查是否游戏结束
        if(state.mistakes >= state.maxMistakes) {
            gameOver(false);
        }
    }

    // 更新菜单按钮状态
    function updateMenuButtons() {
        const hasSavedGame = localStorage.getItem("sudokuCurrentGame") !== null;
        elements.continueGameBtn.disabled = !hasSavedGame;
    }

    // 游戏结束
    function gameOver(success) {
        stopGame();
        
        // 更新游戏进度
        const difficultyKey = getDifficultyKey(state.difficulty);
        state.progress[difficultyKey][state.currentLevel-1] = success;
        
        // 保存进度
        saveProgress();
        
        // 设置游戏结束弹窗内容
        let difficultyText;
        switch(state.difficulty) {
            case 1: difficultyText = "容易"; break;
            case 2: difficultyText = "中等"; break;
            case 3: difficultyText = "困难"; break;
            case 4: difficultyText = "专家"; break;
            default: difficultyText = "中等";
        }
        
        elements.difficultyDisplay.textContent = difficultyText;
        elements.levelDisplay.textContent = state.currentLevel;
        
        // 格式化时间
        const minutes = Math.floor(state.timeElapsed / 60);
        const seconds = state.timeElapsed % 60;
        elements.timeDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        
        // 设置游戏结果
        elements.gameResult.textContent = success ? "恭喜通关!" : "游戏失败!";
        
        // 设置下一关信息
        const nextLevelAvailable = state.currentLevel < 20 && success;
        elements.nextLevelInfo.textContent = success 
            ? (nextLevelAvailable ? "下一关卡已解锁!" : "这是最后一关!") 
            : "游戏失败!";
        
        elements.nextLevelBtn.style.display = success && nextLevelAvailable ? "block" : "none";
        
        // 显示游戏结束弹窗
        showGameOver();
    }

    // 显示游戏结束弹窗
    function showGameOver() {
        elements.gameOverPopup.classList.add("active");
        elements.overlay.classList.add("active");
    }

    // 隐藏游戏结束弹窗
    function hideGameOver() {
        elements.gameOverPopup.classList.remove("active");
        elements.overlay.classList.remove("active");
    }

    // 停止游戏
    function stopGame() {
        clearInterval(state.timer);
        state.timer = null;
        state.isPlaying = false;
    }

    // 下一关
    function nextLevel() {
        hideGameOver();
        
        // 检查是否有下一关
        if(state.currentLevel < 20) {
            startLevel(state.currentLevel + 1);
        } else {
            // 已经是最后一关，返回关卡选择
            showLevelMenu(state.difficulty);
        }
    }

    // 重新开始当前关卡
    function playAgain() {
        hideGameOver();
        startLevel(state.currentLevel);
    }

    // 加载游戏
    function loadGame() {
        const savedGame = localStorage.getItem("sudokuCurrentGame");
        
        if(savedGame) {
            try {
                const gameState = JSON.parse(savedGame);
                
                // 恢复基本状态
                state.difficulty = gameState.difficulty;
                state.currentLevel = gameState.level;
                state.board = gameState.board;
                state.solution = gameState.solution;
                state.notes = gameState.notes;
                state.timeElapsed = gameState.timeElapsed;
                state.mistakes = gameState.mistakes;
                state.moves = gameState.moves;
                state.notesMode = gameState.notesMode;
                state.isPlaying = true;
                
                // 恢复选中的单元格
                if(gameState.selectedCell) {
                    state.selectedCell = {
                        row: gameState.selectedCell.row,
                        col: gameState.selectedCell.col,
                        element: null // 将在renderBoard后设置
                    };
                }
                
                // 更新UI
                updateMenuButtons();
                renderBoard();
                
                // 设置关卡信息
                let difficultyText;
                switch(state.difficulty) {
                    case 1: difficultyText = "容易"; break;
                    case 2: difficultyText = "中等"; break;
                    case 3: difficultyText = "困难"; break;
                    case 4: difficultyText = "专家"; break;
                    default: difficultyText = "中等";
                }
                
                elements.levelInfo.textContent = `关卡 ${state.currentLevel} ${difficultyText}`;
                
                // 更新红心显示
                updateHearts();
                
                // 开始计时
                startTimer();
                
                // 切换到游戏页面
                elements.gamePage.classList.add("active");
                
                // 恢复选中单元格的高亮
                if(state.selectedCell) {
                    const index = state.selectedCell.row * 9 + state.selectedCell.col;
                    state.selectedCell.element = elements.sudokuBoard.children[index];
                    state.selectedCell.element.classList.add("highlighted");
                }
            } catch(e) {
                console.error("加载游戏失败:", e);
                alert("加载保存的游戏时出错,将开始新游戏");
                showDifficultyMenu();
            }
        } else {
            alert("没有找到可继续的游戏!");
        }
    }

    // 保存当前游戏
    function saveCurrentGame() {
        const gameState = {
            difficulty: state.difficulty,
            level: state.currentLevel,
            board: state.board,
            solution: state.solution,
            notes: state.notes,
            timeElapsed: state.timeElapsed,
            mistakes: state.mistakes,
            moves: state.moves,
            notesMode: state.notesMode,
            selectedCell: state.selectedCell ? {
                row: state.selectedCell.row,
                col: state.selectedCell.col
            } : null
        };
        
        localStorage.setItem("sudokuCurrentGame", JSON.stringify(gameState));
    }

    // 保存进度
    function saveProgress() {
        localStorage.setItem("sudokuProgress", JSON.stringify(state.progress));
    }

    // 加载进度
    function loadProgress() {
        const savedProgress = localStorage.getItem("sudokuProgress");
        if(savedProgress) {
            state.progress = JSON.parse(savedProgress);
        }
    }

    // 生成数独谜题
    function generatePuzzles() {
        // 实际应用中应该有更复杂的生成算法
        
        
        for(let i = 0; i < 20; i++) {
            // 容易难度
            state.puzzles.easy.push(generatePuzzle(1));
            
            // 中等难度
            state.puzzles.medium.push(generatePuzzle(2));
            
            // 困难难度
            state.puzzles.hard.push(generatePuzzle(3));
            
            // 专家难度
            state.puzzles.expert.push(generatePuzzle(4));
        }
    }

   
    function generatePuzzle(difficulty) {
        // 生成已解决的数独棋盘
        const solution = generateSolvedBoard();
        
        // 根据难度移除不同数量的数字
        let cellsToRemove;
        switch(difficulty) {
            case 1: cellsToRemove = 30; break; // 容易
            case 2: cellsToRemove = 40; break; // 中等
            case 3: cellsToRemove = 50; break; // 困难
            case 4: cellsToRemove = 55; break; // 专家
            default: cellsToRemove = 40;
        }
        
        // 创建谜题副本
        const puzzle = JSON.parse(JSON.stringify(solution));
        
        // 随机移除单元格
        let removed = 0;
        while(removed < cellsToRemove) {
            const row = Math.floor(Math.random() * 9);
            const col = Math.floor(Math.random() * 9);
            
            if(puzzle[row][col] !== 0) {
                puzzle[row][col] = 0;
                removed++;
            }
        }
        
        return { puzzle, solution };
    }

    // 生成已解决的数独棋盘
    function generateSolvedBoard() {
        const board = Array(9).fill().map(() => Array(9).fill(0));
        
        // 填充对角线上的3x3宫格
        for(let box = 0; box < 9; box += 3) {
            fillBox(board, box, box);
        }
        
        // 解决剩余部分
        solveSudoku(board);
        return board;
    }

    // 填充3x3宫格
    function fillBox(board, row, col) {
        const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        shuffleArray(nums);
        
        let index = 0;
        for(let i = 0; i < 3; i++) {
            for(let j = 0; j < 3; j++) {
                board[row + i][col + j] = nums[index++];
            }
        }
    }

    // 打乱数组
    function shuffleArray(array) {
        for(let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }

    // 解数独
    function solveSudoku(board) {
        for(let i = 0; i < 9; i++) {
            for(let j = 0; j < 9; j++) {
                if(board[i][j] === 0) {
                    for(let num = 1; num <= 9; num++) {
                        if(isValid(board, i, j, num)) {
                            board[i][j] = num;
                            if(solveSudoku(board)) {
                                return true;
                            }
                            board[i][j] = 0;
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    // 检查数字是否有效
    function isValid(board, row, col, num) {
        // 检查行
        for(let j = 0; j < 9; j++) {
            if(board[row][j] === num) return false;
        }
        
        // 检查列
        for(let i = 0; i < 9; i++) {
            if(board[i][col] === num) return false;
        }
        
        // 检查3x3宫格
        const boxRow = Math.floor(row / 3) * 3;
        const boxCol = Math.floor(col / 3) * 3;
        
        for(let i = 0; i < 3; i++) {
            for(let j = 0; j < 3; j++) {
                if(board[boxRow + i][boxCol + j] === num) return false;
            }
        }
        
        return true;
    }

    // 公开方法
    return {
        init
    };
})();

// 当DOM加载完成后初始化游戏
document.addEventListener('DOMContentLoaded', SudokuGame.init);
